<!-- 自定义配置config基本结构，仅供参考 -->
<!--
    type : 主要声明用于序号以及选择框
    checked： 展示与隐藏
    disabled: 是否可选择显示隐藏，为true表示不可勾选。永久展示
    width： 每一个列所占据的宽度，不定义则自动生成
    name：对应的后台返回的键值字段名
    label： 前端要呈现的中文名字
    formatter： 自定义的其他事务。配合type使用
    fixed: 是否固定列，参考el-table
    tableHeight：是否自定义高度。不传则默认是当前屏幕下的全部高度
    sortable: 是否开启排序，参考el-table
    1.如果type等于edit，并且formatter有值，标识改列作为编辑/删除使用/，formatter格式请看下表，默认编辑name值为Edit,删除为Delete，对应el-icon中图标名字
    2.如果type等于change，并且formatter有值，标识作为自定义文字所使用，formatter格式请看下表
    ---注：1-1.如果需要符号定义，比如￥100，则在formatter中增加sign属性即可，sign值为需要的符号
           1-2.如果字体需要更换颜色，则在formatter中增加color属性即可
           1-3.如果文字需要增加单位，则在formatter中增加unit属性即可
    3.如果type等于status，并且formatter有值，将呈现自定义按钮样式，formatter格式请看下表
    --注：1-1.如果文字需要按钮样式，则在formatter中增加status属性即可。status默认有primary/danger/warning/success/default 5种样式，如需增加，请在下方style样式中按格式添加，然后在/assets/element/index.scss 中添加全局样式
    如果返回值为数组格式或者1,2,3这种多个字符串形式，将自动以多个子元素的形式呈现；如果1，2，3这种类型的字符串不需要特殊处理，请不要传入type值，传入type值等于status默认都会被处理
    4.如果type等于dot，并且formatter有值，将呈现脉冲圆点样式，formatter格式请看下表
     -->
<!-- [
  { name: 'index', label: '序号', width: '80', type: 'index/selection', checked: true },
  { name: 'date', label: '日期', width: '', checked: true },
  { name: 'name', label: '姓名', width: '', checked: true },
  { name: 'address', label: '地址', width: '', checked: true },
  { name: 'total', label: '总数', width: '', checked: false },
  ******增加文字修饰符
  { name: 'gender', label: '性别', width: '', type: 'status',checked: false,formatter: [
      { name: '1', label: '男',sign:'￥' },
      { name: '2', label: '女',color:'red',unit: '份' }
    ] },
    ******按钮形态展示
    { name: 'gender', label: '性别', width: '', type: 'status',checked: false,formatter: [
      { name: '1', label: '男',stutus:'primary' },
      { name: '2', label: '女',stutus:'danger' }
    ] },
    ******脉冲圆点
    {
    name: 'gender',
    label: '性别',
    width: '',
    checked: true,
    type: 'dot',
    formatter: [
      { name: '1', label: '男', status: 'primary' },
      { name: '2', label: '女', status: 'danger' }
    ]
  },
  *******按钮组
  {
    name: '',
    label: '操作',
    width: '',
    type: 'edit',
    checked: true,
    formatter: [
      { name: 'Edit', label: '编辑', link: false, font: true },
      { name: 'Add', label: '添加', link: false, font: true, icon: 'Edit' },
      { name: 'Delete', label: '删除' },
      { name: 'Refresh', label: '重置',font: true }
    ]
  }
] -->

<!-- ********************** -->
<!-- 其他说明 -->
<!-- 当type=edit时，按钮可以有多种呈现方式 -->
<!-- 1.当link：false,表示不启用文字按钮，将以按钮形式出现。默认为true -->
<!-- 2.另外可以配置其他多种属性，呈现不同的展示方式
  （1）font：true，表示需要文字展示。这时文字将会取值label，默认为false
  （2）icon：String，需要icon图标，填入icon名称，不要则不传
 -->
<template>
  <div class="bg-common-content-box" id="table-box" :style="tableCustomer">
    <!-- <div class="loading-flex-box" v-show="props.showLoading">
                        <el-icon class="is-loading"> <Loading /> </el-icon>加载数据中...
                      </div> -->
    <LoadingPanel :loading="props.showLoading"></LoadingPanel>
    <div class="table-coms-box">
      <TableIcon v-if="props.iconShow" :config="props.config" @changeAlign="changeAlign" :iconFlex="props.iconFlex">
        <slot></slot>
      </TableIcon>
      <el-table :data="props.data" ref="table" style="width: 100%" v-loading="props.loading"
        element-loading-text="loading..." :show-summary="props.showSummary" :summary-method="getSummaries" border
        :max-height="props.tableHeight == 0
          ? Number(store.tableHeight) - 45
          : Number(props.tableHeight) - 60
          " @selection-change="handleSelectionChange" :header-cell-style="{ padding: '12px 0', background: '#F2F3F5' }"
        row-key="uuid" :tree-props="{ children: 'children', hasChildren: 'hasChildren' }">
        <template v-for="(item, index) in props.config" :key="index">
          <el-table-column v-if="item.checked" :prop="item.name" :label="item.label" :type="item.type"
            :fixed="item.fixed" :sortable="item.sortable" :align="props.align ? props.align : align" :width="item.width"
            :show-overflow-tooltip="item.type == 'change'">
            <template v-slot="scope">
              <!-- 自定义组装格式 -->
              <template v-if="item.type == 'custom'">
                <div class="title-flex-box">
                  <el-icon color="#D9D9D9">
                    <Memo />
                  </el-icon>
                  <div class="info-flex-box">
                    <div class="title">{{ scope.row.title }}</div>
                    <div class="subTitle">
                      <span>{{ scope.row.create_time }}</span>
                      <span></span>
                      <span>{{ scope.row.create_username }}</span>
                    </div>
                  </div>
                </div>
              </template>
              <template v-if="item.type == 'edit' &&
  item.formatter &&
  item.formatter.length > 0
">
                <!-- <el-button v-for="(k, i) in item.formatter" :key="i" :type="k.type ? k.type : 'primary'"
                                    :size="k.size ? k.size : 'small'" :icon="k.icon ? k.icon : k.link == null ? k.name : ''"
                                    @click="btnChanged(scope.row, k)" :link="k.link != null ? k.link : true">
                                    {{ k.font ? k.label : '' }}
                                  </el-button> -->
                <template
                  v-for="(k, i) in item.formatter.length > 3 ? item.formatter.slice(0, item.limit) : item.formatter"
                  :key="i">
                  <el-button 
                    class="el-button el-button--primary is-link" 
                    :type="k.type ? k.type : 'primary'" 
                    :icon="k.icon && !k.iconfont ? k.icon : k.link == null ? k.name : ''" 
                    @click="handleButtonClick(scope.row, k, $event)"  
                    :link="k.link != null ? k.link : true"
                    :disabled="k.disabled && scope.row[k.key]">
                    {{ k.isArry ? Formate(k.label, scope.row[k.value]) : k.font ? k.label : '' }}
                    <template #icon v-if="k.iconfont && k.icon">
                      <el-icon style="cursor: pointer;" :size="16">
                        <SvgIcon :icon-class="k.icon" :color="Number(scope.row.face_status) == 0
                          ? '#FF5562'
                          : Number(scope.row.face_status) == 1
                            ? '#76C74E'
                            : '#FF9F32'
                          "></SvgIcon>
                      </el-icon>
                    </template>
                  </el-button>
                  <el-dropdown size="large" v-if="item.formatter.length > item.limit && i == item.limit - 1"
                    style="margin-left:12px;">
                    <el-button type="primary" :link="true">
                      <el-icon>
                        <MoreFilled />
                      </el-icon>
                    </el-button>
                    <template #dropdown>
                      <el-dropdown-menu style="width: 100%;" :append-to-body="false">
                        <div
                          v-show="(y.name != 'move' && y.name != 'titlel' && y.name != 'configl' && y.name != 'timesl' && y.name != 'pack' && y.name != 'generate' && y.name != 'edits' && y.name != 'clears' && y.name != 'releases')"
                          v-for="(y, j) in item.formatter.slice(item.limit)" :key="j">
                          <el-dropdown-item @click="btnChanged(scope.row, y)" icon="" :command="y.name">
                            <i :class="`icon iconfont ${y.icon}`" style="margin-right:8px;"></i>
                            {{ y.label }}
                          </el-dropdown-item>
                        </div>
                      </el-dropdown-menu>
                    </template>
                  </el-dropdown>
                </template>
              </template>
              <template v-if="item.type == 'editStatus' &&
                item.formatter &&
                item.formatter.length > 0
              ">
                <template v-for="(k, i) in item.formatter" :key="i">
                  <el-button 
                    v-if="k.label == Formate2(k.name, scope.row, k.label)"
                    :type="k.status ? k.status : 'primary'" 
                    :size="k.size ? k.size : 'small'"
                    :icon="k.icon ? k.icon : k.link == null ? k.name : ''" 
                    @click="handleButtonClick(scope.row, k, $event)"
                    :link="k.link != null ? k.link : true" 
                    :disabled="scope.row.disabled">
                    {{ Formate2(k.name, scope.row, k.label) }}
                  </el-button>
                </template>
              </template>
              <!-- 图片格式 -->
              <template v-else-if="item.type == 'images'">
                <el-image :src="scope.row[item.name]" @click="handlePictureCardPreview(scope.row[item.name])"
                  fit="cover"
                  style="width: 32px; height: 32px;border-radius: 50%;cursor: pointer;display: inline-block;"></el-image>
              </template>
              <template v-else-if="item.type == 'images2'">
                <el-image :src="scope.row[item.name]" @click="handlePictureCardPreview(scope.row[item.name])"
                  fit="cover"
                  style="width: 100px; height: 48px;cursor: pointer;display: inline-block;border-radius: 4px;"></el-image>
              </template>
              <!-- 标签格式-->
              <template v-else-if="item.type == 'label'">
                <span size="small" type="primary" v-if="scope.row[item.name].length > 0" plain style="display: inline-block;padding: 0px 8px;border-radius: 3px;
border: 1px solid #B52427;color: #B52427;font-size: 12px;margin: 2px;"
                  v-for="(items, indexs) in scope.row[item.name] ? scope.row[item.name].split(',').slice(0, 2) : scope.row[item.name].split(',')"
                  :key="indexs">{{
                    items }}</span>
                <span v-else>-</span>
              </template>
              <!-- 如果存在图标 -->
              <template v-else-if="item.type == 'icon'">
                <span :class="'icon iconfont ' + scope.row[item.name]"></span>
              </template>
              <template v-else-if="item.type == 'change'">
                <span v-if="scope.row[item.name] == '' || scope.row[item.name] == null
                ">-</span>
                <span v-else>{{ scope.row[item.name] }}</span>
              </template>
              <!-- 纯文字，字体换颜色 -->
              <template v-else-if="item.type == 'change' &&
                item.formatter &&
                item.formatter.length > 0
              ">
                <span v-if="scope.row[item.name] == '' || scope.row[item.name] == null
                ">-</span>
                <div v-else :style="changeFormatter(
                  scope.row,
                  item.name,
                  item.formatter,
                  scope.$index
                )
                  ? 'color:' +
                  changeFormatter(
                    scope.row,
                    item.name,
                    item.formatter,
                    scope.$index
                  )
                  : ''
                  ">
                  {{ changeFormatter(scope.row, item.name, item.formatter) }}
                </div>
              </template>
              <!-- 自定义按钮形式，一般用于状态按钮呈现 -->
              <template v-else-if="item.type == 'status' &&
                item.formatter &&
                item.formatter.length > 0
              ">
                <span v-if="scope.row[item.name] === '' || scope.row[item.name] === null
                ">-</span>
                <template v-else>
                  <!-- 单个的情况 -->
                  <template v-if="typeof scope.row[item.name] == 'string' ||
                    typeof scope.row[item.name] == 'number'
                  ">
                    <div class="status-content-box" :style="statusCustomer">
                      <div class="table-status-view" :style="item.formatter.length == 1
                        ? 'color:' + item.formatter[0].color
                        : ''
                        " :class="getClassName(scope.row, item.name, item.formatter)
                          ">
                        {{
                          changeFormatter(scope.row, item.name, item.formatter)
                        }}
                      </div>
                    </div>
                  </template>
                  <!-- 数组的情况 -->
                  <!-- 1.字符串分割的形式/数组的形式 -->
                  <template v-else-if="typeof scope.row[item.name] == 'object' ||
                    scope.row[item.name].split(',').length > 1
                  ">
                    <div class="table-array-box" :style="statusCustomer">
                      <div class="status-content-box" v-for="(k, i) in scope.row[item.name]" :key="i"
                        v-if="typeof scope.row[item.name] == 'object'">
                        <div class="table-status-view" :class="getClassArrayName(k, item.formatter)">
                          {{ changeArrayFormatter(k, item.formatter) }}
                        </div>
                      </div>
                      <div class="status-content-box" v-for="(k, i) in scope.row[item.name].split(',')" :key="i"
                        v-if="typeof scope.row[item.name] == 'string'">
                        <div class="table-status-view" :class="getClassArrayName(k, item.formatter)">
                          {{ changeArrayFormatter(k, item.formatter) }}
                        </div>
                      </div>
                    </div>
                  </template>
                </template>
              </template>
              <!-- 是否需要转换成脉冲圆点的形式 -->
              <template v-else-if="item.type == 'dot' &&
                item.formatter &&
                item.formatter.length > 0
              ">
                <span v-if="scope.row[item.name] == '' || scope.row[item.name] == null
                ">-</span>
                <Dot v-else :status="getDotName(scope.row, item.name, item.formatter)"></Dot>
              </template>
              <!-- switch开关操作情况 -->
              <template v-else-if="item.type == 'switch'">
                <el-switch v-model="scope.row[item.name]" :active-value="item.activevalue"
                  :inactive-value="item.inactivevalue" active-color="#00BE65" inactive-color="#cccccc"
                  @change="handleChanged(scope.row)">
                </el-switch>
              </template>
              <template v-else-if="item.colorType">
                <span :style="Number(scope.row[item.name]) > 0 ? 'color:#00C35A' : 'color: red;'">{{
                  scope.row[item.name]
                }}</span>
              </template>
            </template>
          </el-table-column>
        </template>
      </el-table>
    </div>
    <!-- <teleport to="#table-box"> -->
    <Pagination v-if="props.showPage" v-bind="$attrs" :total="Number(props.total)" :align="props.pageAlign">
    </Pagination>
    <!-- </teleport> -->
    <el-image-viewer v-if="dialogVisible" @close="closeViewer" :url-list="srcList"></el-image-viewer>
  </div>
</template>
<script lang="ts" setup>
// import $util from '../../util/util'
import TableIcon from './TableIcon.vue'
import Dot from './Dot.vue'
import { PiniaStore } from '../../store'
import { ref, onMounted, watch, nextTick, computed, onUnmounted } from 'vue'
import LoadingPanel from './LoadingPanel.vue'
interface PropsType {
  //   集合
  data?: any
  totalMoney?: number | string
  // 条数
  total?: number | string
  //   自定义的展示数据
  config?: any
  // 是否需要顶部边距
  marginTop?: boolean
  // page翻页器的排版方式。可选值center/flex-end/flex-start
  pageAlign?: string
  // Popover气泡数据
  faceInfo?: any
  // 是否需要翻页器
  showPage?: boolean
  // 自定义icon的栅栏布局
  iconFlex?: number
  // 自定义容器高度
  tableHeight?: number | string
  // 是否需要呈现table顶部分栏条件
  iconShow?: boolean
  // 是否需要加载层遮罩
  showLoading?: boolean
  align?: string
  showSummary?: boolean
  loading?: boolean
}
const props = withDefaults(defineProps<PropsType>(), {
  tableData: [],
  marginTop: true,
  totalMoney: 0,
  total: 100,
  pageAlign: 'center',
  showPage: true,
  iconFlex: 16,
  tableHeight: 0,
  showLoading: false,
  iconShow: true,
  config: [],
  align: '',
  showSummary: false,
  loading: false
})
interface EmitType {
  (e: 'handleEdit', item: any, val: string): void
  (e: 'selectionChanged', val: object[]): void
  (e: 'handleInfo', item: any): void
  (e: 'statusChanged', item: any): void
  (e: 'getSummaryTotal', item: any): void
}
const emit = defineEmits<EmitType>()
// 添加焦点处理方法
const handleButtonClick = (row: any, btnConfig: any, event: MouseEvent) => {
  // 执行原有的点击逻辑
  btnChanged(row, btnConfig);
  // 修复：通过类名 .el-button 定位按钮根元素
  const buttonEl: any = event.target instanceof HTMLElement 
    ? event.target.closest('.el-button')  // 修改此处：将 'el-button' 改为 '.el-button'
    : null;
  if (buttonEl) {
    // 延迟执行确保样式更新
    nextTick(() => {
      buttonEl.blur();
    });
  }
};
const getSummaries = (param: any) => {
  if (props.totalMoney) {
    const { columns, data } = param;
    const sums = <any>[]; //声明变量
    columns.forEach((column: any, index: number) => {
      if (index === 0) {
        sums[index] = "合计";
        return;
      }
      const values = data.map((item: any) => Number(item[column.property]));
      if (
        column.property == "money" || column.property == "settlement_amount" //需要显示和合计纵列
      ) {
        sums[index] = props.totalMoney
        sums[index] = '￥' + sums[index];
      } else {
        sums[index] = '-';
      }
    })
    return sums;
  } else {
    const { columns, data } = param;
    const sums = <any>[];
    columns.forEach((column: any, index: number) => {
      if (index === 0) {
        sums[index] = '合计';
        return;
      }
      const values = data.map((item: any) => Number(item[column.property]));
      if (!values.every((value: any) => isNaN(value))) {
        sums[index] = values.reduce((prev: any, curr: any,) => {
          const value = Number(curr);
          if (!isNaN(value)) {
            return prev + curr;
          } else {
            return prev;
          }
        }, 0);
        sums[index] = sums[index].toFixed(2)
      } else {
        sums[index] = '-';
      }
    });

    return sums;
  }
}
const store = PiniaStore()
//   排版方式.left/center/right
const align = ref('center')
const table = ref<any>(null)
const statusCustomer = computed(() => {
  if (align.value === 'center' && !props.align) {
    return 'justify-content:center;'
  } else if (props.align === 'left') {
    return 'justify-content:flex-start;'
  } else if (align.value === 'left') {
    return 'justify-content:flex-start;'
  } else {
    return 'justify-content:flex-end;'
  }
})
const tableCustomer = computed(() => {
  let cssStyle = ''
  if (props.marginTop) {
    cssStyle +=
      'border-top: 10px solid #F3F5F8;height:' +
      (store.mainHeight - store.searchHeight)
    'px;'
  } else if (store.searchHeight > 0) {
    cssStyle += 'height:' + (store.mainHeight - store.searchHeight + 13) + 'px;'
  } else {
    cssStyle += 'height:' + (store.mainHeight - 50) + 'px;'
  }
  if (props.tableHeight !== 0) {
    cssStyle += 'height:' + props.tableHeight + 'px;'
  }
  if (!props.iconShow) {
    cssStyle += 'padding:0;'
  }
  return cssStyle
})
const changeAlign = (val: string) => {
  align.value = val
}
const rowClass = (row: any, column: any, rowIndex: any, columnIndex: any) => {
  console.log(row.rowIndex, props.data.length - 1)
  if (row.rowIndex === props.data.length - 1) {
    return 'fixed-row'
  }
}
// 点击按钮触发父元素函数
const btnChanged = (item: any, type: any) => {
  emit('handleEdit', item, type.name)
}
// 点击弹出冒泡弹窗
const btnPop = (item: any) => {
  emit('handleInfo', item)
}
// 如果开启了单选或多选，触发父元素相关函数
const handleSelectionChange = (val: object[]) => {
  emit('selectionChanged', val)
}
const getClassName = (row: any, val: any, list: any) => {
  let className: string = 'default'
  list.forEach((item: any, index: any) => {
    if (item.name === row[val]) {
      className = 'table-status--' + item.status
    }
  })
  return className
}
const getDotName = (row: any, val: any, list: any) => {
  let className: string = 'default'
  list.forEach((item: any, index: any) => {
    if (item.name === row[val]) {
      className = item.status
    }
  })
  return className
}
const handleChanged = (row: any) => {
  emit('statusChanged', row)
}
const changeFormatter = (row: any, val: any, list: any, $index?: number) => {
  let returnVal: string = ''
  list.forEach((item: any, index: any) => {
    if (item.name === row[val]) {
      if ($index && item.color !== null) {
        returnVal = item.color
      } else if ($index && item.type) {
        returnVal = item.type
      } else {
        returnVal = item.label
        if (item.sign) {
          returnVal = item.sign + item.label
        }
        if (item.unit) {
          returnVal = item.label + item.unit
        }
      }
    } else {
      if (item.sign) {
        returnVal = item.sign + row[val]
      }
      if (item.unit) {
        returnVal = row[val] + item.unit
      }
    }
  })
  return returnVal
}
// 处理数组类型
const changeArrayFormatter = (val: any, list: any) => {
  let returnVal: string = ''
  list.forEach((item: any, index: any) => {
    if (item.name === val) {
      returnVal = item.label
    }
  })
  return returnVal
}
const getClassArrayName = (val: any, list: any) => {
  let className: string = 'default'
  list.forEach((item: any, index: any) => {
    if (item.name === val) {
      className = 'table-status--' + item.status
    }
  })
  return className
}
const Formate = (item: any, value: any) => {
  let name = ''
  item.forEach((items: any) => {
    if (Number(items.value) === Number(value)) {
      name = items.name
    }
  })
  return name
}
const Formate2 = (value: any, item: any, items: any) => {
  let name = ''
  if (Number(item.status) === Number(value)) {
    name = items
  }
  return name
}
// 查看图片
const srcList = ref<any>([])
const dialogVisible = ref(false)
const closeViewer = () => {
  dialogVisible.value = false
}
const handlePictureCardPreview = (url: any) => {
  srcList.value = []
  srcList.value.push(url)
  dialogVisible.value = true
}
</script>
<style lang="scss" scoped>
.bg-common-content-box {
  background-color: var(--el-color-white);
  padding: 15px 0 0 0;
  box-sizing: border-box;
  // position: relative;
  border-radius: 0 0 10px 10px;
}

.status-content-box {
  display: flex;
  padding: 2.5px;

  .table-status-view {
    padding: 0 12px;
    border-radius: 3px;
  }
}

.table-array-box {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
}

.table-status--default {
  color: $default-color;
  font-size: 12px;
  background-color: $default-Bg-Color;
}

.table-status--primary {
  color: $primary-color;
  font-size: 12px;
  background-color: $primary-Bg-Color;
}

.table-status--success {
  color: $success-color;
  font-size: 12px;
  background-color: $success-Bg-Color;
}

.table-status--danger {
  color: $danger-color;
  font-size: 12px;
  background-color: $danger-Bg-Color;
}

.table-status--warning {
  color: $warning-color;
  font-size: 12px;
  background-color: $warning-Bg-Color;
}

.table-coms-box {
  padding: 0 15px;
}

.title-flex-box {
  display: flex;
  align-items: baseline;

  .info-flex-box {
    margin-left: 10px;

    .title {
      font-size: 16px;
      font-weight: 500;
      color: #333333;
      text-align: left;
    }

    .subTitle {
      display: flex;
      align-items: center;
      font-size: 12px;
      color: #999999;

      span {
        display: inline-block;
      }

      span:nth-of-type(2) {
        display: inline-block;
        margin: 0 10px;
        width: 1px;
        height: 10px;
        background: #E5E5E5;
      }
    }
  }
}

.el-dropdown {
  vertical-align: middle;
}

.el-button.is-link {
  margin-left: 12px;
}

.el-button.is-link:first-of-type {
  margin-left: 0px;
}

.lang-select-dropdown {
  position: absolute !important;
  top: 0px !important;
  left: 0px !important;
}
</style>
<style>
.el-popper.is-dark{
  max-width: 300px !important;
  /* 可选：允许文本换行 */
  white-space: normal;
  word-wrap: break-word;
}
</style>